package gee

import (
	"fmt"
	"log"
	"net/http"
	"runtime"
	"strings"
	"time"
)

// handle url pattern by slice
func parsePattern(pattern string) []string {
	patternArr := strings.Split(pattern, "/")
	parts := make([]string, 0)

	for _, item := range patternArr {
		if item != "" {
			parts = append(parts, item)
			if item[0] == '*' {
				break
			}
		}
	}

	return parts
}

// log processing middleware
func Logger() HandlerFunc {
	return func(ctx *Context) {
		startTime := time.Now()

		ctx.Next()

		log.Printf("[%d] %s in %v", ctx.StatusCode, ctx.Req.RequestURI, time.Since(startTime))
	}
}

// custom track file show
func trace(message string) string {
	var pcs [32]uintptr
	// skip first 3 caller
	n := runtime.Callers(5, pcs[:])

	var str strings.Builder
	str.WriteString(message + "\nTraceback:")
	for _, pc := range pcs[:n] {
		fn := runtime.FuncForPC(pc)
		file, line := fn.FileLine(pc)
		str.WriteString(fmt.Sprintf("\n\t%s:%d", file, line))
	}

	return str.String()
}

// panic process middleware
func Recovery() HandlerFunc {
	return func(c *Context) {
		defer func() {
			if err := recover(); err != nil {
				message := fmt.Sprintf("%s", err)
				log.Printf("%s\n\n", trace(message))
				c.String(http.StatusInternalServerError, "Internal Server Error")
			}
		}()
		c.Next()
	}
}
